from django.http import Http404
from rest_framework import exceptions
from rest_framework.exceptions import APIException
from django.utils.translation import gettext_lazy as _
from rest_framework.views import set_rollback
from django.core.exceptions import PermissionDenied as PermissionDeny

from gesture_demo_server.common.my_middleware import HandleRequestException
from gesture_demo_server.common.result import ResultCode, BaseResponse


class NotFound(APIException):
    status_code = ResultCode.MSG_NO_MATCHING_ERROR
    default_detail = _(ResultCode.MSG_NO_MATCHING_ERROR)


class PermissionDenied(APIException):
    status_code = ResultCode.CODE_AUTH_ERROR
    default_detail = _(ResultCode.MSG_AUTH_ERROR)


def my_exception_handler(exc, context):
    """
    返回应用于任何给定异常的响应。

    默认情况下，会处理rdf框架的' APIException '，以及Django内置的' Http404 '和' PermissionDenied '异常。
    对于其他异常，将由HandleRequestException.process_exception方法进行处理

    """
    if isinstance(exc, Http404):
        exc = NotFound()
    elif isinstance(exc, PermissionDeny):
        exc = PermissionDenied()

    if isinstance(exc, exceptions.APIException):
        headers = {}
        if getattr(exc, 'auth_header', None):
            # noinspection PyUnresolvedReferences
            headers['WWW-Authenticate'] = exc.auth_header
        if getattr(exc, 'wait', None):
            # noinspection PyUnresolvedReferences
            headers['Retry-After'] = '%d' % exc.wait

        if isinstance(exc.detail, (list, dict)):
            data = exc.detail
        else:
            data = {'detail': exc.detail}

        set_rollback()
        return BaseResponse(code=exc.status_code, data=data)

    return HandleRequestException.process_exception(exception=exc)
